import configparser
import networkx as nx
from pyvis.network import Network
import matplotlib
matplotlib.use('Agg')  # 防止交互模式冲突
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg

def load_config():
    """读取配置文件并返回知识图谱数据"""
    config = configparser.ConfigParser()
    try:
        with open('config.ini', 'r', encoding='utf-8') as f:  # 指定编码
            config.read_file(f)
    except UnicodeDecodeError:
        # 处理含 BOM 头的 UTF-8 文件
        with open('config.ini', 'r', encoding='utf-8-sig') as f:
            config.read_file(f)

    knowledge_data = {}
    root_name = config.get('KnowledgeGraph', 'root_name')
    categories = config.get('KnowledgeGraph', 'categories').split(', ')
    knowledge_data[root_name] = categories

    for category in categories:
        subtopics = config.get(category, 'subtopics').split(', ')
        knowledge_data[category] = subtopics

    return knowledge_data

def build_graph(knowledge_data):
    """构建知识图谱结构"""
    G = nx.DiGraph()
    for parent, children in knowledge_data.items():
        G.add_node(parent, size=30, title=parent, group="category")
        for child in children:
            G.add_node(child, size=20, title=child, group="concept")
            G.add_edge(parent, child, label="包含")
    return G

def plot_static_graph(G):
    """静态可视化（Matplotlib）"""
    fig = plt.figure(figsize=(12, 8))
    canvas = FigureCanvasAgg(fig)  # 显式绑定画布
    pos = nx.spring_layout(G, seed=42)
    nx.draw(G, pos, with_labels=True, node_size=2000, node_color="skyblue", font_size=10)
    edge_labels = nx.get_edge_attributes(G, 'label')
    nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
    plt.title("Java知识图谱 - 静态视图")
    canvas.draw()  # 渲染图像
    plt.show()

def plot_interactive_graph(G):
    """动态可视化（PyVis）"""
    net = Network(notebook=True, height="600px", width="100%", bgcolor="#222222", font_color="white")
    net.from_nx(G)
    net.show_buttons(filter_=['physics'])
    net.show("java_knowledge_graph.html")

if __name__ == "__main__":
    # 1. 加载配置
    knowledge_data = load_config()
    print("配置文件加载成功！")

    # 2. 构建图谱
    G = build_graph(knowledge_data)
    print("知识图谱构建完成！")

    # 3. 可视化
    plot_static_graph(G)
    plot_interactive_graph(G)
    print("可视化完成！静态图已显示，动态图保存为 java_knowledge_graph.html")